﻿Imports System.Collections.Specialized

Namespace Data

    ' The data model defined by this file serves as a representative example of a strongly-typed
    ' model that supports notification when members are added, removed, or modified.  The property
    ' names chosen coincide with data bindings in the standard item templates.
    '
    ' Applications may use this model as a starting point and build on it, or discard it entirely and
    ' replace it with something appropriate to their needs.

    ''' <summary>
    ''' Base class for <see cref="SampleDataItem"/> and <see cref="SampleDataGroup"/> that
    ''' defines properties common to both.
    ''' </summary>
    <Windows.Foundation.Metadata.WebHostHidden>
    Public MustInherit Class SampleDataCommon
        Inherits Common.BindableBase

        Public Sub New(uniqueId As String, title As String, subtitle As String, imagePath As String, description As String)
            Me._uniqueId = uniqueId
            Me._title = title
            Me._subtitle = subtitle
            Me._imagePath = imagePath
            Me._description = description
        End Sub

        Private Shared _baseUri As New Uri("ms-appx:'''")

        Private _uniqueId As String = String.Empty
        Public Property UniqueId As String
            Get
                Return Me._uniqueId
            End Get
            Set(value As String)
                Me.SetProperty(Me._uniqueId, value)
            End Set
        End Property

        Private _title As String = String.Empty
        Public Property Title As String
            Get
                Return Me._title
            End Get
            Set(value As String)
                Me.SetProperty(Me._title, value)
            End Set
        End Property

        Private _subtitle As String = String.Empty
        Public Property Subtitle As String
            Get
                Return Me._subtitle
            End Get
            Set(value As String)
                Me.SetProperty(Me._subtitle, value)
            End Set
        End Property

        Private _description As String = String.Empty
        Public Property Description As String
            Get
                Return Me._description
            End Get
            Set(value As String)
                Me.SetProperty(Me._description, value)
            End Set
        End Property

        Private _image As ImageSource
        Private _imagePath As String
        Public Property Image As ImageSource
            Get
                If Me._image Is Nothing AndAlso Me._imagePath IsNot Nothing Then
                    Me._image = New BitmapImage(New Uri(SampleDataCommon._baseUri, Me._imagePath))
                End If
                Return Me._image
            End Get

            Set(value As ImageSource)
                Me._imagePath = Nothing
                Me.SetProperty(Me._image, value)
            End Set
        End Property

        Public Sub SetImage(path As String)
            Me._image = Nothing
            Me._imagePath = path
            Me.OnPropertyChanged("Image")
        End Sub

        Public Overrides Function ToString() As String
            Return Me.Title
        End Function
    End Class

    ''' <summary>
    ''' Generic item data model.
    ''' </summary>
    Public NotInheritable Class SampleDataItem
        Inherits SampleDataCommon

        Public Sub New(uniqueId As String, title As String, subtitle As String, imagePath As String, description As String,
                       content As String, group As SampleDataGroup)
            MyBase.New(uniqueId, title, subtitle, imagePath, description)
            Me._content = content
            Me._group = group
        End Sub

        Private _content As String = String.Empty
        Public Property Content As String
            Get
                Return Me._content
            End Get
            Set(value As String)
                SetProperty(Me._content, value)
            End Set
        End Property

        Private _group As SampleDataGroup
        Public Property Group As SampleDataGroup
            Get
                Return Me._group
            End Get
            Set(value As SampleDataGroup)
                SetProperty(Me._group, value)
            End Set
        End Property

    End Class

    ''' <summary>
    ''' Generic group data model.
    ''' </summary>
    Public NotInheritable Class SampleDataGroup
        Inherits SampleDataCommon

        Public Sub New(uniqueId As String, title As String, subtitle As String, imagePath As String, description As String)
            MyBase.New(uniqueId, title, subtitle, imagePath, description)
        End Sub

        Private WithEvents _items As New ObservableCollection(Of SampleDataItem)()
        Public ReadOnly Property Items As ObservableCollection(Of SampleDataItem)
            Get
                Return Me._items
            End Get
        End Property

        Private _topitems As New ObservableCollection(Of SampleDataItem)()
        Public ReadOnly Property TopItems As ObservableCollection(Of SampleDataItem)
            Get
                Return Me._topitems
            End Get
        End Property

        Private Sub ItemsCollectionChanged(sender As Object, e As NotifyCollectionChangedEventArgs) Handles _items.CollectionChanged
            ' Provides a subset of the full items collection to bind to from a GroupedItemsPage
            ' for two reasons: GridView will not virtualize large items collections, and it
            ' improves the user experience when browsing through groups with large numbers of
            ' items.
            '
            ' A maximum of 12 items are displayed because it results in filled grid columns
            ' whether there are 1, 2, 3, 4, or 6 rows displayed

            Select Case e.Action
                Case NotifyCollectionChangedAction.Add
                    If e.NewStartingIndex < 12 Then
                        TopItems.Insert(e.NewStartingIndex, Items(e.NewStartingIndex))
                        If TopItems.Count > 12 Then
                            TopItems.RemoveAt(12)
                        End If
                    End If
                Case NotifyCollectionChangedAction.Move
                    If e.NewStartingIndex < 12 And e.OldStartingIndex < 12 Then
                        TopItems.Move(e.OldStartingIndex, e.NewStartingIndex)
                    ElseIf e.OldStartingIndex < 12 Then
                        TopItems.RemoveAt(e.OldStartingIndex)
                        TopItems.Add(Items(11))
                    ElseIf e.NewStartingIndex < 12 Then
                        TopItems.Insert(e.NewStartingIndex, Items(e.NewStartingIndex))
                        TopItems.RemoveAt(12)
                    End If
                Case NotifyCollectionChangedAction.Remove
                    If e.OldStartingIndex < 12 Then
                        TopItems.RemoveAt(e.OldStartingIndex)
                        If Items.Count >= 12 Then
                            TopItems.Add(Items(11))
                        End If
                    End If
                Case NotifyCollectionChangedAction.Replace
                    If e.OldStartingIndex < 12 Then
                        TopItems(e.OldStartingIndex) = Items(e.OldStartingIndex)
                    End If
                Case NotifyCollectionChangedAction.Reset
                    TopItems.Clear()
                    While TopItems.Count < Items.Count And TopItems.Count < 12
                        TopItems.Add(Items(TopItems.Count))
                    End While
            End Select
        End Sub

    End Class

    ''' <summary>
    ''' Creates a collection of groups and items with hard-coded content.
    ''' 
    ''' SampleDataSource initializes with placeholder data rather than live production
    ''' data so that sample data is provided at both design-time and run-time.
    ''' </summary>
    Public NotInheritable Class SampleDataSource
        Private Shared _sampleDataSource As New SampleDataSource()

        Private _allGroups As New ObservableCollection(Of SampleDataGroup)
        Public ReadOnly Property AllGroups As ObservableCollection(Of SampleDataGroup)
            Get
                Return Me._allGroups
            End Get
        End Property

        Public Shared Function GetGroups(uniqueId As String) As IEnumerable(Of SampleDataGroup)
            If Not uniqueId.Equals("AllGroups") Then Throw New ArgumentException("Only 'AllGroups' is supported as a collection of groups")

            Return _sampleDataSource.AllGroups
        End Function

        Public Shared Function GetGroup(uniqueId As String) As SampleDataGroup

            ' Simple linear search is acceptable for small data sets
            Dim matches As IEnumerable(Of SampleDataGroup) = _sampleDataSource.AllGroups.Where(Function(group) group.UniqueId.Equals(uniqueId))
            If matches.Count() = 1 Then Return matches.First()
            Return Nothing
        End Function

        Public Shared Function GetItem(uniqueId As String) As SampleDataItem

            ' Simple linear search is acceptable for small data sets
            Dim matches As IEnumerable(Of SampleDataItem) = _sampleDataSource.AllGroups.SelectMany(Function(group) group.Items).Where(Function(item) item.UniqueId.Equals(uniqueId))
            If matches.Count() = 1 Then Return matches.First()
            Return Nothing
        End Function

        Public Sub New()
            Dim ITEM_CONTENT As String = String.Format("Since this application does not really do anything, the onlything you can do here is...nothing...")

            Dim group1 As New SampleDataGroup("Group-1",
                    "Customers",
                    "Control your customer here",
                    "Assets/red.png",
                    "Group Description: With this group you can do...nothing at all...")
            group1.Items.Add(New SampleDataItem("Group-1-Item-1",
                    "Add Customer",
                    "Here you could add a customer",
                    "Assets/lightred.png",
                    "Note: Not yet implemeneted",
                    ITEM_CONTENT,
                    group1))
            group1.Items.Add(New SampleDataItem("Group-1-Item-2",
                    "Remove Customer",
                    "Here you can remove a Customer",
                    "Assets/lightred.png",
                    "Note: Not yet implemeneted",
                    ITEM_CONTENT,
                    group1))
            group1.Items.Add(New SampleDataItem("Group-1-Item-3",
                    "Modify Customer",
                    "Here you can modify the customer",
                    "Assets/lightred.png",
                    "Note: Not yet implemeneted",
                    ITEM_CONTENT,
                    group1))
            Me.AllGroups.Add(group1)

            Dim group2 As New SampleDataGroup("Group-2",
                    "Users",
                    "Access control for users in ths application",
                    "Assets/green.png",
                    "Group Description")
            group2.Items.Add(New SampleDataItem("Group-2-Item-1",
                    "Add User",
                    "Selecct this to add a user",
                    "Assets/lightgreen.png",
                    "Note: Not yet implemeneted",
                    ITEM_CONTENT,
                    group2))
            group2.Items.Add(New SampleDataItem("Group-2-Item-2",
                    "Remove User",
                    "Select this to remove a user",
                    "Assets/lightgreen.png",
                    "Note: Not yet implemeneted",
                    ITEM_CONTENT,
                    group2))
            group2.Items.Add(New SampleDataItem("Group-2-Item-3",
                    "Report a user",
                    "Select this to report a user and to get him fired",
                    "Assets/lightgreen.png",
                    "Note: Not yet implemeneted",
                    ITEM_CONTENT,
                    group2))
            Me.AllGroups.Add(group2)

            Dim group3 As New SampleDataGroup("Group-3",
                    "Settings",
                    "Change your settings here",
                    "Assets/yellow.png",
                    "Note: Not yet implemeneted")
            group3.Items.Add(New SampleDataItem("Group-3-Item-1",
                    "Modify Coulors",
                    "Every app needs this dumb function",
                    "Assets/lightyellow.png",
                    "Note: Not yet implemeneted",
                    ITEM_CONTENT,
                    group3))
            group3.Items.Add(New SampleDataItem("Group-3-Item-2",
                    "Modify the Performance",
                    "Here you can make the application slower if it is to fast",
                    "Assets/lightyellow.png",
                    "Note: Not yet implemeneted",
                    ITEM_CONTENT,
                    group3))
            group3.Items.Add(New SampleDataItem("Group-3-Item-3",
                    "Enable AutoPilot",
                    "Using the autopilot you can go home",
                    "Assets/lightyellow.png",
                    "Note: Not yet implemeneted",
                    ITEM_CONTENT,
                    group3))
            Me.AllGroups.Add(group3)
        End Sub

    End Class

End Namespace
